home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-03
/
dosbasic.zip
/
ASM.ZIP
/
P1.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-12-19
|
29KB
|
712 lines
;«RM82»«TS8,16,24,32,40,48,56»
;Updated 12/13/90
;============================================================================
; Copyright (C) Copr. 1990 by Sidney J. Kelly
; All Rights Reserved.
; Sidney J. Kelly
; 150 Woodhaven Drive
; Pittsburgh, PA 15228
; home phone 412-561-0950 (7pm to 9:30pm EST)
;============================================================================
DOSSEG
.model medium
.code
public PRINTRDY, CHECK87, FREERAM, EQUIPMENT, OTHERMEMORY, FINDDRIVES, ANSICHECK, ACTUALEXTND
; Please do not remove
Copyright DB 13,10,'Copyright Copr. (C) 1990 Sidney J. Kelly',13,10
Copyright1 DB 'All Rights Reserved',13,10,26
;==========================================================================
;DECLARE FUNCTION PRINTRDY%(Lpt%)
; Input:
; Lpt% gives portnumber to test
; Lpt%=1 for LPT1:, 2 for LPT2:, etc
;
; Returns:
; 0 if not ready
; -1 (True) if ready
;===========================================================================
EVEN
PRINTRDY PROC FAR ; Check LPT(Lpt%):
Push BP
Mov BP,SP
Mov BX,[BP+6]
Mov DX,[BX]
Dec DX ; 0 biased
Cmp DX,4 ; make sure Lpt# is 0 to 3
JB @f ;
Xor AX,AX ; report out of range error
Jmp Short EXIT_1
@@:
Mov AH, 2 ; Check printer status for
Int 17h ; Printer bios interrupt
Mov DX, AX ; Put result in DX &
Xor AX, AX ; assume no printer
TEST DH, 00101001b ; Are any error bits on?
JNE EXIT_1 ; Yes? Error so exit
TEST DH, 10010000b ; Are both operation bits on?
JZ EXIT_1 ; No? Error so exit
Mov AX,-1 ; Printer on line, returns -1
EXIT_1: ; Error or offline, returns 0
Pop BP
Ret 2 ; quits program & clears parameter
PRINTRDY Endp
;=======================================================================
;DECLARE FUNCTION CHECK87%()
;Returns:
; 0 if no 80x87, or system equipment word not set.
; 87 if an 8087
; -87 if 8087 emulation in use on an 80286 or 80386. Because the
; the 80287 has almost exactly the same instruction set as the
; 8087 few have felt a need to emulate the 80287. I have not
; seen an 80387 emulator in software. The 80827 just includes
; one new instruction (protected mode), nothing for use in
; real mode. 80387 has transendental math routines.*
;
; 287 if an 80827
; 387 if an 80387 or 80487
; More accurate than checking the equipment word. QBX, Version 7
; merely checks the equipment word to determine if an 80x87 is installed.
; I guess that can be used as a software toggle.
;
; * Intel recently released an 80287 that has 80387 transendental math
; routines in it. If someone sends me a new chip, I will write code
; to test for it.
;
; Because of complaints about the traditional test with inexpensive clones
; (See Jon Waterhouse letter in Byte, Nov. 1990, page 40)
; routine first tests the equipment word in RAM bios.
;=======================================================================
;
; REFERENCES:
; basic info is adopted from Ted Forgeron's article in PC
; Tech Journal, Aug '87 p43.
; Copr. 1987 Pat Shea - Psi! (that Copr. is on there cuz my
; lawyer sez I should, but feel
; free to hack away!!! pats.)
; In the event of subsequent republication of this function,
; please carry forward reference to these two gentlemen as
; original authors.
;
; Minor beautification, addition of MASM 5.1 simplified
; directives, detection of emulation, additional commentary by SJK 12/12/90
;
; The CX loop idea for slow PC's with a math chip is from the public
; domain INFOPLUS Version 1.35, Andrew Rossman 10/7/90
;=======================================================================
EVEN
CTRL_Word dw 0 ; CTRL_Word word needed for the NDP test.
; In OS/2 probably will have to make
; this a local variable on the stack
; because cannot write to CSegment in
; OS/2.
EVEN
CHECK87 PROC FAR
Pushf ; save flags
; in response to clone errors, test to see if system knows
; if math chip is installed. If Int 11h sez no, then
; report no mathchip. Can't check AT CMOS mathchip bit
; because some clones do not set the bit in the CMOS, but
; only set the bit in the Int 11h equipment word. E.g. ACER 910
Int 11h
Test AL,10b ; is mathchip bit Set?
JZ No_Math_Chip ; no mathchip
;Test for any mathchip
Mov Word Ptr CTRL_Word,0h ; clear CTRL_Word
CLI ; prevent interrupts so routine will work on slow PC's
; The next two 80x87 instructions cannot carry the WAIT prefix,
; because there may not be an 80x87 for which to wait. The WAIT is
; therefore emulated with a MOV CX,<value>! LOOP $ combination. This
; allow use of routine on an old PC with an 8087.
Fninit ; try to initialize the NDP
; use the no-wait state version of the op code so will not
; hang a machine without a NDP. Loop allows test of a PC that
; does have an 8087.
Mov CX,2 ; a time waste loop
Loop $ ; allow 8087 time to react
Fnstcw CTRL_Word ; put CTRL_Word in memory
; use the no-wait state version of the op code so will not
; hang a machine without a NDP. Loop allows test of a PC that
; does have an 8087.
Mov CX,14h
Loop $
STI ; allow interrupts again
Cmp byte ptr CTRL_Word+1, 3 ; if high byte = 3h then NDP found
Je chk_87 ; found something, so keep going
No_Math_Chip:
Xor AX,AX ; else zero AX to show
Jmp SHORT CHK_87_END ; no NDP
;Test for 8087
chk_87:
And CTRL_Word,NOT 0080h ; turn ON interrupts (IEM = 0)
Fldcw CTRL_Word ; load CTRL_Word word
Fdisi ; turn OFF interrupts (IEM = 1)
Fstcw CTRL_Word ; store CTRL_Word word
Test CTRL_Word,0080h ; if IEM=1, 8087 (only 8087 pays
; attention to IEM)
Jz Chk_287 ; not an 8087, test for 80287
;-------------------------------------------------------------------------
; Test for 8087 emulation by software. Emulation only can be done on an
; 80286 or 80386. So test for an 80286 or 80386 using quirk with flags
; I haven't seen a routine that emulates the 80287 so this is not tested
; for. I am sure one exists though. Emulation of an 8087/808287 is possible
; because of a special bit on the 80287 machine status register. Exactly how
; this emulation is done is light years beyond me.
; The only reason for testing for emulation is suggest to user that he
; would get faster results if he relied on MS QuickBasic built in
; software emulation rather than other forms of software emulation.
;-------------------------------------------------------------------------
Xor AX,AX ; clear AX
Push AX ; put on stack
Popf ; put in flags
Pushf ; put back on stack
Pop AX ; get flags back in AX
And AX,0F000h ; clear all but upper 4 bits
Cmp AX,0F000h ; if bits 12-15 are set then CPU
JE @f ; is not an 80286, 80386 or 80486
Mov AX,-87 ; put -87 in AX to show that
Jmp SHORT CHK_87_END ; emulation is detected
@@:
; CPU is a NEC, 8086/88 or 80186/88
Mov AX,87 ; put 87 in AX to show
Jmp SHORT CHK_87_END ; found an 8087
;Test for 80287
Chk_287:
Finit ; set default infinity mode
Fld1 ; push 1 on stack
Fldz ; push 0 on stack
Fdiv ; then divide. Make infinity
; by dividing 1 by zero
Fld St ; push back on stack. Change
Fchs ; sign & make negative infinity
Fcompp ; compare the two infinities
; Default after FINIT for 80287 & 8087 is projective infinity where
; both positive and negative infinity are equal. 80387 & 80486 use
; affine infinity, and ignore projective infinity. Under affine
; infinity positive and negative infinity are at opposite ends of the
; number line and are not equal. (SJK Who thinks of these things???)
Fstsw CTRL_Word ; store status for result
Fwait ; wait until status word is stored
Mov AX,CTRL_Word ; get CTRL_Word word
Sahf ; put highbyte (AH) into flags
Jnz Got_387 ; If bit 6 (infinity control)
; not set then it is a 80387
Mov AX,287 ; report that it is an 80287
; since we tested for an 8087
Jmp SHORT CHK_87_END
; NDP not an 8087 or an 80287 so it must be an 80387. The 80387 ignores
; the infinity control (IC) flag, 80287/8087 does not. SJK
Got_387:
Mov AX,387 ; return 387
CHK_87_END:
Popf ; restore flags
ret ; end, return to main routine
CHECK87 ENDP
;===========================================================================
; DECLARE SUB EQUIPMENT(ConvMem%,PrinterPorts%,ComPorts%)
; Returns amount of Conventional Memory in KB
; number of Parallel Ports
; number of COM ports
;===========================================================================
ConvMem EQU [BP+10]
PrinterPorts EQU [BP+8]
ComPorts EQU [BP+6]
EVEN
EQUIPMENT PROC FAR
Push BP ; save stack frame
Mov BP,SP ; address stack
Int 12h ; get conventional memory
Mov BX,ConvMem ; point to ConvMem%
Mov [BX],AX ; Place value in ConvMem%
Xor DX,DX ; clear DX for use
Int 11h ; Call get equipment interrupt
Mov AL,AH ; just look at top 8 bits
; save them in AH
; use AL to manipulate
Mov CL,06 ; Dump bits 8-13,
SHR AL,CL ; and move 14 & 15 to lower positions
And AL,03 ; mask any other positions
Mov DL,AL ; Move Printers%
Mov BX,PrinterPorts ; Point to PrinterPorts%
Mov [BX],DX ; And store in PrinterPorts%
Mov AL,AH ; Get top 8 bits again
SHR AL,1 ; This time look at bits 9, 10 & 11
And AL,07 ; by masking for 3 bits
Mov DL,AL ; And move ComPorts to DL
Mov BX,ComPorts ; Point to ComPorts%
Mov [BX],DX ; And store in ComPorts%
Pop BP ; restore BP
Ret 6 ; remove 2*3 parameters
EQUIPMENT Endp
;======================================================================
; DECLARE SUB OTHERMEMORY(EXTENDED%,EXPANDED%,XMS%)
; Returns size of extended, expanded, and XMS memory.
; Extended = only size that BIOS reports is free
; Expanded = total installed.
; XMS = total installed.
;
; Uses the rom ID byte approach to determine if extended memory supported.
;======================================================================
.code
EXPMEM DB "EMMXXXX0"
EXPMEM_LENGTH EQU $-EXPMEM
EVEN
Drv_ADDR DD 0 ; This will hold address of
; HIMEM.SYS driver
EVEN
OTHERMEMORY PROC FAR
Push BP
Mov BP,SP ; save all registers used
Push DI
Push SI
;---------------------------------------------------------------------------
; Find Extended Memory Size
;---------------------------------------------------------------------------
Xor BX,BX ; assume no extended memory
Mov AX,0FFFFh ; Read system byte
Mov ES,AX ; Store segment in ES
Mov AL,ES:[0EH] ; Get System ID.
Cmp AL,0FCh ; Check if AT, PS/2 Model 50 & 60
; most AT clones use same code too
; including COMPAQ 286 & 386 machines
; PS/2 Model 30/286, AT&T 6300 Plus
; Tandy AT clones, etc.
JZ Find_Extended ; If AT, get extended.
Cmp AL,0F8h ; Check if &HF8: Model 80 & Model 70
; or Model 55SX
JZ Find_Extended ; OK, get extended.
Jmp Short Exnted_Exit ; else exit, because PC, XT, JR,
; Convertible, Model 25, 30, other.
Find_Extended:
Mov AH,88h ; Retrieve extended memory size.
CLC ; a fix for IBMCACHE
; documented in P.C. Mag
; June 27, 1989, page 303 EMS40.SYS
; same fix in XMS.SYS version 2.03
Int 15h ; value returned in AX
JC Exnted_Exit ; If carry set, then error.
; This should stop errors in clones
; too.
Mov BX,AX ; o.k., store value in BX temporarily
Exnted_Exit:
STI ; I think this will prevent crash on
; AT&T 6300 (though an AT&T 6300 would
; not get this far). AT&T bios error
; is the failure to reset interrupts??
; This should not be a problem with
; AT&T 6300 Plus and later models
; after calling Int 15h
Mov AX,BX ; get value from BX & store in AX
Mov BX,[BP+10]
Mov [BX],AX ; store back in integer variable
;---------------------------------------------------------------------------
;Find Expanded Memory Size
;---------------------------------------------------------------------------
Mov AX,3567h ; Retrieve EMM interrupt vector.
Int 21h ; stores result in ES:BX
Xor BX,BX ; Assume no expanded memory.
Mov DI,0Ah ; Set DI to offset 10 of vector
Cld ; clear the direction flag
Push DS ; Save DS
Mov AX,CS
Mov DS,AX ; Set DS to CS
Assume DS:@code
Mov SI,OFFSET CS:EXPMEM ; DS:SI points to EMMXXXX0.
Mov CX,EXPMEM_LENGTH ; CX has length of "EMMXXXX0"
REPZ CMPSB ; ES:DI destination, DS:SI source
Pop DS ; restore DS
Assume DS:@data
JNZ EXPANDED_EXIT ; If no, then no LIM manager.
Mov AH,42h ; Else, retrieve free expanded.
Int 67h ; returns free pages in BX
; total pages in DX
Xor BX,BX ; clear BX to catch errors
Or AH,AH ; if AH = 0 then EMS is ok
JZ @f ; so jump forward, else
Mov BX,-1 ; report EMS with error
Jmp Short EXPANDED_EXIT ; EMS error so exit
@@:
Mov AX,16 ; multiply total page count by 16
Mul DX ; this converts DX pages to KB
; result in DX:AX
Mov BX,AX ; store AX in BX temporarily
EXPANDED_EXIT:
Mov AX,BX ; get value from BX & store in AX
Mov BX,[BP+8]
Mov [BX],AX
;---------------------------------------------------------------------------
; XMS Memory test
; Source: XMS Specs (Microsoft 1989)
; Note unless you have version 2.06 or higher, information is not accurate
; i.e. 64kb of HIMEM area is reported as free when that is not so.
; This routine will adjust free XMS if version <2.06 and >1.xx. The only
; common version with this error is Version 2.04.
;---------------------------------------------------------------------------
Mov AH,30h ; test DOS version
Int 21h ; if less than 3.x XMS does
Cmp AL,3 ; not exist
JB XMS_err ; so quit now
Mov AX,4300h ; call Int 2Fh function. Int 2Fh
Int 2Fh ; wasn't initialized before DOS 3.xx
Cmp AL,80h
Je XMS1 ; XMS exists so jump forward
XMS_err:
Mov AX,0 ; XMS does not exist or error
Jmp Short XMS_end ; so exit
XMS1:
Mov AX,4310h ; get address of XMS driver
Int 2Fh ; from ES:BX
Mov Word Ptr Drv_ADDR,BX ; save far pointer
Mov Word Ptr Drv_ADDR+2, ES ; from XMS for use below
Xor AH,AH ; call function 0
Call [Drv_ADDR] ; indirect far call to driver
Cmp AX,0200h ; if not version 2 or above
Jb XMS_err ; then quit, too old to be useful
Xor DI,DI ; Assume minor version is 2.06 or
; above
Cmp BX,0206h ; check minor version (BCD number)
Jae FindFree ; verion o.k., so we will skip ahead
;---------------------------------------------------------------------------
; Minor versions before Version 2.06 incorrectly reported HMA as part of free
; XMS space, SO LONG AS none of the XMS had been allocated. As soon as any
; space was allocated the amount of purported free space was corrected.
; Version 2.06 corrected this bug. Most recent version of HIMEM.SYS is
; Version 2.60, July 1990. Existence of error observed with Version 2.04,
; (10/6/88), the version that came with Windows 286.
;---------------------------------------------------------------------------
Mov DI,64 ; remember to eliminate 64kb from
; amount reported as free
FindFree:
Mov AH,08
Call [Drv_ADDR] ; indirect far call to driver
Or AX,AX ; if AX <> 0
JNZ XMS2 ; then no error occured
Cmp BL,0A0h ; if BL set (all XMS allocated)
JZ XMS2 ; then no error,
BadNum:
Mov DX,-1 ; else report XMS error
; for all other error codes
Jmp Short PropVer
XMS2:
Or DI,DI ; was version less than 2.06?
JZ PropVer ; nope, so skip ahead
Mov CX,DX ; store DX in CX
; CMOS routine destroys AX,DX
;------------------------------------------------------------------------------
; Solution to problem is to compare amount of Extended Memory installed
; with amount of XMS free. If number is the same, the HIMEM area is
; erronously included in XMS free number and we have to reduce XMS free
; by 64 kb in verions before 2.06.
;------------------------------------------------------------------------------
Mov AL,48 ; tell CMOS want to look at
Out 70h,AL ; byte in register 48
In AL,71h ; the low byte of extended memory
Mov BL,AL ; store in BL
Mov AL,49 ; tell CMOS want to look at
Out 70h,AL ; byte in register 49
In AL,71h ; the high byte of extended memory
Mov BH,AL ; store in BH
Mov DX,CX ; get XMS free value back again
Cmp DX,BX ; total free = total installed?
; if no, then some space has been
; allocated in XMS so do not have to
; make a correction.
JNE PropVer ; no, so skip ahead as no adjustment
; is necessary
Sub DX,DI ; else reduce free mem. by HMA space
PropVer:
Mov AX,DX ; store free memory in AX
; KB of free extended in AX
XMS_end:
Mov BX,[BP+6] ; get address of last parameter
Mov [BX],AX ; store AX in XMS%
;Final Cleanup
Pop SI ; restore all the registers we used
Pop DI
Pop BP
Ret 6 ; 2 * 3 parameters
OTHERMEMORY Endp
;===========================================================================
; DECLARE FUNCTION FINDDRIVES% ()
; Returns number of current logical drives w/o any errors
;
; Because LASTDRIVE default value = 5, it is likely that
; number of logical drives will be less than LASTDRIVE in CONFIG.SYS
; This routine will miss a drive if there are gaps between logical drives
; as can occur if SUBST is used.
;===========================================================================
.code
EVEN
Storage DB 0
EVEN
FINDDRIVES PROC FAR
Push BP
Mov BP,SP
Mov AH,19h ; read default drive
Int 21h
Mov CS:Storage,AL ; store default in Storage
Mov AH,30h ; read DOS version
Int 21h
Cmp AL,02 ; if less than 3.xx then exit
JBE Dos_Ver2 ; because DOS ver <3.xx returns total number
; of logical drives in AL so we don't
; need to test.
Mov DL,CS:Storage ; put default back in DL
Main_Loop:
Mov AH,0Eh ; select default drive
Inc DL ; add one to the current default
Int 21h ; read next drive above current
Mov AH,19h ; read default drive
Int 21h
Cmp AL,DL ; did default change?
JZ Main_Loop ; yes so jump back
Push DX ; save next drive
Mov DL,CS:Storage ; reload current
Mov AH,0Eh ; select orginal drive
Int 21h
Pop DX ; get next drive
Mov AL,DL ; store in AL
Jmp Short Exit_Routine
Dos_Ver2:
Mov DL,CS:Storage ; reset current
Mov AH,0Eh ; In version 2, max logical drives in AL
Int 21h ; in version 2, min number of drives is 2
Exit_Routine:
Xor AH,AH ; clear AH, since limit is 26 logical drives
Xor DX,DX
Pop BP
Ret ; exit
FINDDRIVES Endp
;============================================================================
; DECLARE FUNCTION ANSICHECK%()
; IF ANSICHECK% THEN
; PRINT "ANSI.SYS is installed."
;
; Source: Disassembled COMMAND.COM Version 3.3 of CLS command
; xxxx:2B62h is the beginning of the routine
;
; VERY FAST and NOT MESSY!!!!
;
;This is the same method that COMMAND.COM uses to test for ANSI.SYS
;so every utility had better allow for this testing method.
;
; NOTE: PC Magazine's ANSI.COM even if turned off will still report ANSI.SYS
; present, (it was planned that way so it would handle CLS).
;============================================================================
EVEN
ANSICHECK PROC FAR
Push BP
Mov CX,-1 ; assume that ANSI is installed
Mov AX,3529h ; get address of INT 29h (FAST PUTCHAR)
Int 21h
Mov DX,ES ; store segment in DX
Mov AX,3520h ; get address of INT 20h, terminate function
Int 21h ; INT 20h usually points to COMMAND.COM
Mov AX,ES
Cmp DX,AX ; if segment for INT 29 > INT 20 then ANSI
JA Ender1 ; is installed
Xor CX,CX ; else, ANSI not installed
Ender1:
Mov AX,CX ; store status in AX
Xor DX,DX
Pop BP
Ret
ANSICHECK ENDP
COMMENT |
The following routine is included just to show an alternative method. To use
remove the comment and add name to PUBLIC
;===========================================================================
; DECLARE FUNCTION OTHERANSI ()
; OTHERANSI
;
; RETURNS
; 0 if ANSI.SYS or ANSI.COM not installed
; -1 if ANSI.SYS or ANSI.COM installed
;
; Theory:
; Uses DOS CON driver to request ANSI cursor report. If ANSI is
; installed cursor report will store current cursor location in CON.
; The curor report is a minimum of 6 bytes long, and it could
; be longer. Therefore, routine clears out CON driver.
;
; Failure to clean out CON means DOS will read garbage as a file
; load request at end of QBASIC program. QBASIC never reads CON,
; only reads the keyboard. DOS reads CON when running COMMAND.COM.
; This detection method is a reliable, though messy way, to do it
; because it will overwrite display if ANSI is not installed.
;
; Caution:
; If ANSI is not loaded will overwrite display at current BIOS cursor
; location. QBASIC routine should set cursor with LOCATE and overwrite
; area with text if ANSI not found. DOS appears to write only to page 0
;===========================================================================
.code
EVEN
CursReport DB 27,'[6n$' ; ANSI Report Cursor sequence
EVEN
OTHERANSI PROC FAR
Push BP
Push DS
Mov AX,0C00h ; clear keyboard buffer
Int 21h ; using a safe method
; there are faster methods
Mov AX,CS
Mov DS,AX ; make DS == CS
Assume DS:@code ; DOS uses DS:DX to point to
; source of Output String
Mov DX, OFFSET CursReport ; ANSI CMD to get cursor position
Mov AH, 9 ; Write ANSI escape sequence DS:DX
Int 21h ; to display with DOS String output
Mov AH, 6 ; Read & ignore Esc character
Mov DL, 0FFh ; in keyboard buffer
Int 21h
JZ ErrorExit ; If ZF set, then ANSI not loaded
Mov AH, 6 ; Read & ignore "[" character
Int 21h
JZ ErrorExit ; If ZF set, then ANSI not loaded
Mov AH, 6 ; Get 1st digit of cursor row
Int 21h
JZ ErrorExit ; If ZF set, then ANSI not loaded
Mov BX, -1 ; Return -1 if ANSI is installed
Jmp SHORT Clear_CON_Loop
ErrorExit:
Sub BX, BX ; Return 0 if ANSI
; driver not installed
Clear_CON_Loop:
Mov AH, 6 ; clear out rest of control
Mov DL, 0FFh ; information from CON
Int 21h ; driver if ANSI is installed
JNZ Clear_CON_Loop ; and cursor not at LOCATE 1,1
Mov AX,BX ; restore value from BX in AX
; for return through function
Pop DS ; restore DS
Assume DS:@data
Pop BP ; restore BP
Ret
OTHERANSI ENDP
|
;============================================================================
; DECLARE FUNCTION ACTUALEXTND% ()
; Returns:
; Actual amount of extended memory installed on 80286, 80386 or 80486
; machine as stored in CMOS RAM
; If clock battery is bad, will return a -1
;============================================================================
EVEN
ACTUALEXTND PROC FAR
Xor BX,BX ; assume no extended memory
Mov AX,0FFFFh ; Read system byte
Mov ES,AX ; Store segment in ES
Mov AL,ES:[0EH] ; Get System ID.
Cmp AL,0FCh ; Check if AT, PS/2 Model 50 & 60
; most AT clones use same code too
; including COMPAQ 286 & 386 machines
; PS/2 Model 30/286, AT&T 6300 Plus
JZ Find_Extended1 ; If AT, get extended.
Cmp AL,0F8h ; Check if &HF8: Model 80 & Model 70
; or Model 55SX
JZ Find_Extended1 ; OK, get extended.
Jmp Short Finis2 ; else exit, because PC, XT, JR,
; Convertible, Model 25, 30, other.
; Can't just test for 80286 chip
; because could be on an accelerator
; board
Find_Extended1:
Mov AL,14 ; see if battery good in
Out 70h,AL ; CMOS status register D
In AL,71h
Test AL,80h ; bit 7 set if battery bad
JNZ Finis3 ; if set quit
Mov AL,48 ; tell CMOS want to look at
Out 70h,AL ; byte in register 48
In AL,71h ; the low byte of extended memory
Mov BL,AL ; store in BL
Mov AL,49 ; tell CMOS want to look at
Out 70h,AL ; byte in register 49
In AL,71h ; the high byte of extended memory
Mov BH,AL ; store in BH
Finis2:
Mov AX,BX ; put BX in AX to report size
Xor DX,DX ; in case call as Long
Ret
Finis3:
Mov BX,-1 ; put -1 in BX if clock battery bad
Jmp Short Finis2
ACTUALEXTND ENDP
END